<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
    <meta charset="utf-8">
    <title>文件拖动排序-样例</title>
    <style media="screen">
        #drag-div { display: block; margin: 10px 50px; width: 520px; border: 1px solid #CCC; overflow: hidden; }
        .drag-item { display: block; position: relative; float: left; width: 120px; height: 120px; border: 1px solid #CCC; margin: 10px; }
        .close { border: 1px solid red; position: absolute; right: 0; width: 17px; height: 17px; z-index: 1; text-align: center; line-height: 17px; }
        .drag-pic { max-width: 100%; position: absolute; top: 0; left: 0; right: 0; bottom: 0; margin: auto; }
    </style>
    <script>
        function dragSort(_ref) {
            var id = _ref.id, // 需拖动元素父级ID
                drag = _ref.drag, // 拖动的元素class（需  draggable="true" 其中  链接和图像默认是可拖动的）
                times = _ref.times; // 拖动动画时长

            if(!times){
                times = 1000
            };
            this.id = id;
            this.drag = drag;
            this.times = times; // 拖动动画时长
            this.init();
        };

        // 给实例对象添加公共属性和方法
        dragSort.prototype = {
            init: function init() {
                var node = document.getElementById(this.id);
                var dragClass = this.drag, _this = this;
                var draging = null;
                //使用事件委托，将li的事件委托给ul
                node.ondragstart = function(event) {
                    // console.log("start");
                    draging = event.target;
                }
                node.ondragover = function(event) {
                    // console.log("onDrop over");
                    event.preventDefault();
                    var target = event.target;
                    if (!_this.hasClassName(target, dragClass)) {
                        target = target.parentNode
                    }
                    // 进行属性判断，是否覆盖到移动的标签上
                    if (_this.hasClassName(target, dragClass)) {
                        if (target && target.animated) {
                            return;
                        }
                        var targetIndex = _this.index(target), dragingIndex = _this.index(draging), nextNode = '', animateObj = [];
                        if (targetIndex != dragingIndex) { // 拖拽框位置判断
                            if (targetIndex > dragingIndex) { // 向后拖拽
                                var preIndex = _this.index(draging),
                                    nextIndex = _this.index(target),
                                    existingnode = target.nextElementSibling;
                            } else { // 向前拖拽
                                var preIndex = _this.index(target),
                                    nextIndex = _this.index(draging),
                                    existingnode = target;
                            }
                            for (var i = 0; i < nextIndex - preIndex + 1; i++) {
                                nextNode = nextNode == "" ? draging : (targetIndex > dragingIndex ? nextNode.nextElementSibling : nextNode.previousElementSibling);
                                animateObj.push([nextNode.getBoundingClientRect(), nextNode])
                            }
                            target.parentNode.insertBefore(draging, existingnode);
                            for (var i = 0; i < animateObj.length; i++) {
                                _this.animate(animateObj[i][0], animateObj[i][1]);
                            }
                        }
                    }
                }
            },
            // 判断是否包含某个class
            hasClassName: function hasClassName(obj, name){
                var tmpName = obj.className;
                var tmpReg = new RegExp(name, 'g');
                return tmpReg.test(tmpName) ? true : false;
            },
            //获取元素在父元素中的index
            index: function _index(el) {
                var index = 0;
                if (!el || !el.parentNode) {
                    return -1;
                }
                while (el && (el = el.previousElementSibling)) {
                    index++;
                }
                return index;
            },
            // 元素移动
            animate: function _animate(prevRect, target) {
                var ms = this.times;
                var _this = this;
                if (ms) {
                    var currentRect = target.getBoundingClientRect();
                    if (prevRect.nodeType === 1) {
                        prevRect = prevRect.getBoundingClientRect();
                    }
                    _this.css(target, 'transition', 'none');
                    _this.css(target, 'transform', 'translate3d(' +
                        (prevRect.left - currentRect.left) + 'px,' +
                        (prevRect.top - currentRect.top) + 'px,0)'
                    );
                    target.offsetWidth; // 触发重绘
                    _this.css(target, 'transition', 'all ' + ms + 'ms');
                    _this.css(target, 'transform', 'translate3d(0,0,0)');

                    clearTimeout(target.animated);
                    target.animated = setTimeout(function() {
                        _this.css(target, 'transition', '');
                        _this.css(target, 'transform', '');
                        target.animated = false;
                    }, ms);
                }
            },
            // 给元素添加style
            css: function _css(el, prop, val) {
                var style = el && el.style;

                if (style) {
                    if (val === void 0) {
                        if (document.defaultView && document.defaultView.getComputedStyle) {
                            val = document.defaultView.getComputedStyle(el, '');
                        } else if (el.currentStyle) {
                            val = el.currentStyle;
                        }
                        return prop === void 0 ? val : val[prop];
                    } else {
                        if (!(prop in style)) {
                            prop = '-webkit-' + prop;
                        }
                        style[prop] = val + (typeof val === 'string' ? '' : 'px');
                    }
                }
            }
        };
    </script>
</head>
<body>
<button onclick="add()" style="margin: 52px 0 0 52px;"> 新增 </button>

<div id="drag-div">
    <div class="drag-item" draggable="true">
        <div class="close" onclick="del(event)">x</div>
        <img src="./img/1.jpg" class="drag-pic" draggable="false">
    </div>
    <div class="drag-item" draggable="true">
        <div class="close" onclick="del(event)">x</div>
        <img src="./img/2.jpg" class="drag-pic" draggable="false">
    </div>
    <div class="drag-item" draggable="true">
        <div class="close" onclick="del(event)">x</div>
        <img src="./img/3.jpg" class="drag-pic" draggable="false">
    </div>
    <div class="drag-item" draggable="true">
        <div class="close" onclick="del(event)">x</div>
        <img src="./img/4.jpg" class="drag-pic" draggable="false">
    </div>
    <div class="drag-item" draggable="true">
        <div class="close" onclick="del(event)">x</div>
        <img src="./img/5.jpg" class="drag-pic" draggable="false">
    </div>
    <div class="drag-item" draggable="true">
        <div class="close" onclick="del(event)">x</div>
        <img src="./img/6.jpg" class="drag-pic" draggable="false">
    </div>
    <div class="drag-item" draggable="true">
        <div class="close" onclick="del(event)">x</div>
        <img src="./img/7.jpg" class="drag-pic" draggable="false">
    </div>
    <div class="drag-item" draggable="true">
        <div class="close" onclick="del(event)">x</div>
        <img src="./img/8.jpg" class="drag-pic" draggable="false">
    </div>
</div>
</body>
<script type="text/javascript">
    var dragSort = new dragSort({
        id : 'drag-div', // 拖动父级div框的ID
        drag: 'drag-item', //拖动元素
        times: '1000', // 动画时长（默认一秒钟）
    })

    function add(event) {
        var node = document.getElementById('drag-div')
        var wrapper= document.createElement('div');
        wrapper.innerHTML= '<div class="drag-item" draggable="true"> <div class="close" onclick="del(event)">x</div> <img src="./img/9.jpg" class="drag-pic" draggable="false"> </div>';
        var html= wrapper.firstChild;
        node.appendChild(html)

    }

    function del(event) {
        // 点击删除当前元素的父级元素
        event.currentTarget.parentElement.parentElement.removeChild(event.currentTarget.parentElement);
    }

</script>
</html>